#ifndef _THREAD_HPP__  // 如果没有定义过 _THREAD_HPP__
#define _THREAD_HPP__  // 则定义 _THREAD_HPP__
#include<iostream>
#include<string>
#include<pthread.h>
#include<functional>
#include <sys/types.h>
#include <unistd.h>


namespace ThreadModule
{
using func_t =std::function<void(std::string name)>;
static int number = 1;
enum class STATUS
{
    NEW,
    RUNNING,
    STOP

};

class Thread 
{
    // void* Route(void* args)   成员函数参数里有this指针 ,start(Route ,nullptr)编不过
    // {

    // }
    static void *Route(void* args)   //static没有传进来this指针 ,也就不能使用成员变量    _name 等等
    {
        Thread* t =static_cast< Thread* >(args);
        t->_status =STATUS::RUNNING;
        t->_func(t->_name);
        return nullptr;
    }
    void EnableDetach()
    {
        _joinable =false;
    }


public:
    Thread(func_t func) :_func(func),_status(STATUS::NEW),_joinable(true)  //创建时传入回调方法
    {
        _name ="Thread-"+std::to_string(number++);
        _pid =getpid();

    }
    
    bool Start()
    {
        if(_status != STATUS::RUNNING)//防止重复启动
        {
            int n =::pthread_create(&_tid ,nullptr, Route ,this );
            if(n !=0) return false;

            _status = STATUS::RUNNING;
            return true;
        }
        return false;
    }

    bool Stop()
    {
        if(_status == STATUS::RUNNING)
        {
            int n= pthread_cancel(_tid);
            if(n!= 0) return false;
            _status = STATUS::STOP;
            return true;
        }
        return false;

    }

    void Detach()
    {
        EnableDetach();
        pthread_detach(_tid);
    }

    bool isjoinable()
    {
        return _joinable;
    }
    bool Join()
    {
        if( _joinable)
        {
            int n =pthread_join(_tid ,nullptr);
            if(n != 0)return false;
            _status =STATUS::STOP;
            return true;
        }
        return false;

    }
    std::string Name()
    {return _name;}

    ~Thread()
    {}
private:
    std::string _name;
    pthread_t _tid;
    pid_t _pid;
    STATUS _status;    //线程结束(stop了)不代表Thread对象结束,因此应该设计线程状态
    bool _joinable ;//是否分离 ,默认不是分离状态, true
    func_t _func;
};

} 



#endif                // 结束条件编译